from uuid import uuid4
import json
import os
from datetime import datetime
from django.db.models import Q

from rest_framework import serializers

from apps.publish.models import *
from .models import *
from util.jsonDeal import JsonTool
from util.initool import IniTool
from util.svn_tool import SvnExport
from util.exception import ValidationError
from django.conf import settings


class DeviceCheckSerializer(serializers.ModelSerializer):
    product_name = serializers.CharField(max_length=200, allow_null=True, allow_blank=True)
    product_number = serializers.CharField(max_length=200, allow_null=True, allow_blank=True)
    order_id = serializers.CharField(max_length=200, allow_null=True, allow_blank=True)
    device_id = serializers.CharField(max_length=200, allow_null=True, allow_blank=True)

    class Meta:
        model = DevicesModel
        fields = ["product_name", "product_number", "order_id", "device_id"]


class DeviceListSerializer(serializers.ModelSerializer):
    class Meta:
        model = DevicesModel
        fields = ["id", "device_id", "order_id", "mcu_id", "product_number", "product_name", ]


class DevicesCreateSerializer(serializers.ModelSerializer):
    product_sum = serializers.IntegerField(allow_null=False)
    product_name = serializers.CharField(max_length=200, allow_null=True, allow_blank=True)
    product_number = serializers.CharField(max_length=200, allow_null=True, allow_blank=True)
    device_id = serializers.CharField(max_length=200, allow_null=True, allow_blank=True)
    order_id = serializers.CharField(max_length=200, allow_null=True, allow_blank=True)
    mcu_id = serializers.CharField(max_length=200, allow_null=True, allow_blank=True)

    def create(self, data):
        sum = data.pop("product_sum")
        for i in range(sum):
            id = str(uuid4()).replace("-", "")
            data["id"] = id
            DevicesModel.objects.create(**data)

    class Meta:
        model = DevicesModel
        fields = ["product_name", "product_number",
                  "device_id" "order_id" "mcu_id"]


class productUpdateSerializer(serializers.ModelSerializer):
    id = serializers.CharField(max_length=50, allow_null=False, allow_blank=False)
    product_name = serializers.CharField(max_length=200, allow_null=True, allow_blank=True)
    product_number = serializers.CharField(max_length=200, allow_null=True, allow_blank=True)
    is_delete = serializers.BooleanField(allow_null=True)

    class Meta:
        model = DevicesModel
        fields = ["id", "is_delete", "product_name", "product_number"]

    def create(self, validated_data):
        data = {}
        for k, v in validated_data.items():
            if v:
                data.update({k: v})
        DevicesModel.objects.filter(id=data["id"]).update(**data)


class productpeizhiSerializer(serializers.ModelSerializer):
    order_id = serializers.CharField(max_length=50, allow_null=False, allow_blank=False)

    class Meta:
        model = DevicesModel
        fields = ["order_id"]

    def create(self, validated_data):
        order_id = validated_data.get("order_id")
        des = DevicesModel.objects.filter(order_id=order_id).all()
        results = []
        for de in des:
            results.append({
                "sql_id": de.id,
                "software_version": de.software_version,
                "hardware_version": de.hardware_version,
            })
        return results


class producthuixieSerializer(serializers.ModelSerializer):
    sn_list = serializers.ListField(max_length=200)

    class Meta:
        model = DevicesModel
        fields = ["sn_list"]

    def create(self, validated_data):
        sn_list = validated_data.get("sn_list")
        for item in sn_list:
            sql_id = item.get("sql_id")
            mcu_id = item.get("mcu_id")
            device_id = item.get("device_id")
            DevicesModel.objects.filter(id=sql_id).update(**{
                "device_id": device_id,
                "mcu_id": mcu_id
            })


class DevicesConfigSingleGet(serializers.ModelSerializer):
    device_id = serializers.CharField(max_length=32, allow_null=False, allow_blank=False)

    def solve(self, data):
        device_id = data.get("device_id")
        de = DevicesModel.objects.filter(id=device_id).first()
        if de:
            product_number = de.product_number
            file_path = de.parameter_file_path
            json_file_path = "{}/{}".format(file_path, "jsonpath")
            os.makedirs(json_file_path, exist_ok=True)
            ori_file_path = "{}/{}".format(file_path, "config")
            os.makedirs(ori_file_path, exist_ok=True)
            get_init_config(product_number, ori_file_path)
            files = os.listdir(ori_file_path)
            if files:
                file_name = files[0]
                head = file_name.split(".")[0]
                ori_file = "{}/{}".format(ori_file_path, file_name)
                with open(ori_file) as f:
                    first = f.readline()
                    if first.startswith("TAC"):
                        flag = "ini"
                    else:
                        flag = "json"
                if flag == "json":
                    json_file = "{}/{}.json".format(json_file_path, head)
                    JsonTool.change_to_json(ori_file, json_file)
                else:
                    json_file = "{}/{}.json".format(json_file_path, head)
                    IniTool.change_to_json(ori_file, json_file)
                with open(json_file) as f:
                    result = json.load(f)
                return result
            else:
                raise ValidationError(300001)

    class Meta:
        model = DevicesModel
        fields = ["device_id"]


class DevicesConfigSerializer(serializers.ModelSerializer):
    items = serializers.DictField(allow_null=False)

    def solve(self, validated_data):
        items = validated_data.get("items")
        ids = []
        for k, v in items.items():
            a = v[0]
            ids.append(a)
        devices = []
        devices_product_number = []
        for i in ids:
            de = DevicesModel.objects.filter(id=i).first()
            devices.append(de)
            devices_product_number.append(de.product_number)
        if len(set(devices_product_number)) != 1:
            raise ValidationError(40003)
        result = {}
        for de in devices:
            product_number = de.product_number
            file_path = de.parameter_file_path
            json_file_path = "{}/{}".format(file_path, "jsonpath")
            os.makedirs(json_file_path, exist_ok=True)
            ori_file_path = "{}/{}".format(file_path, "config")
            os.makedirs(ori_file_path, exist_ok=True)
            get_init_config(product_number, ori_file_path)
            files = os.listdir(ori_file_path)
            if files:
                file_name = files[0]
                head = file_name.split(".")[0]
                ori_file = "{}/{}".format(ori_file_path, file_name)
                with open(ori_file) as f:
                    first = f.readline()
                    if first.startswith("TAC"):
                        flag = "ini"
                    else:
                        flag = "json"
                if flag == "json":
                    json_file = "{}/{}.json".format(json_file_path, head)
                    JsonTool.change_to_json(ori_file, json_file)
                else:
                    json_file = "{}/{}.json".format(json_file_path, head)
                    IniTool.change_to_json(ori_file, json_file)
                with open(json_file) as f:
                    result = json.load(f)
        return result

    class Meta:
        model = DevicesModel
        fields = ["items"]


class DevicesConfigSetSerializer(serializers.ModelSerializer):
    ids = serializers.ListField(allow_null=False)
    result = serializers.ListField(allow_null=False)

    def solve(self, validated_data):
        ids = validated_data.get("ids")
        result = validated_data.get("result")[0]
        result = json.loads(result)
        for d_id in ids:
            de = DevicesModel.objects.filter(id=d_id).first()
            if de:
                file_path = de.parameter_file_path
                json_file_path = "{}/{}".format(file_path, "jsonpath")
                files = os.listdir(json_file_path)
                json_file_name = files[0]
                json_file = "{}/{}".format(json_file_path, json_file_name)
                ori_file_path = "{}/{}".format(file_path, "config")
                files = os.listdir(ori_file_path)
                ori_file_name = files[0]
                ori_file = "{}/{}".format(ori_file_path, ori_file_name)
                with open(json_file) as f:
                    config = json.load(f)
                for name, value in result.items():
                    names = name.split("/")
                    datas = self.__fresh_config(names, value, config)
                if datas:
                    datas = {
                        "data": datas
                    }
                    with open(json_file, "w") as f:
                        json.dump(datas, f)
                    head = datas.get("data")[0].get("head")
                    if head:
                        IniTool.change_to_text(json_file, ori_file)
                    else:
                        JsonTool.chang_to_text(json_file, ori_file)

    def __fresh_config(self, names, value, config):
        if len(names) == 2:
            group = names[0]
            controls_name = names[1]
            node_name = None
        elif len(names) == 3:
            group = names[0]
            controls_name = names[1]
            node_name = names[2]
        else:
            return
        try:
            value = value.get("value")
        except:
            value = value
        datas = config.get("data")
        for item in datas:
            if item.get("group") == group:
                controls = item.get("controls")
                for jtem in controls:
                    if jtem.get("name") == controls_name:
                        if not node_name:
                            jtem["value"] = value
                        else:
                            nodes = controls.get("node")
                            for ktem in nodes:
                                if ktem.get("name") == node_name:
                                    ktem["value"] = value
        return datas

    class Meta:
        model = DevicesModel
        fields = ["ids", "result"]


def get_init_config(product_number, path):
    files = os.listdir(path)
    if not files:
        if not os.path.isdir(path):
            os.makedirs(path)
        pm = PublishDetialModel.objects.filter(product_number=product_number).filter(file_type=3).first()
        if pm:
            version = pm.version
            svn_path = pm.file_path
            os.makedirs(path, exist_ok=True)
            se = SvnExport(svn_path, path, version)
            se.get_origin_file()
        else:
            raise ValidationError(40002)
